package com.xci.platform.helper;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.xci.platform.core.Constant;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.IOException;
import java.lang.reflect.AnnotatedElement;
import java.text.SimpleDateFormat;
import java.util.Date;

public class JsonHelper {
    private final static ObjectMapper mapper;

    static {
        SimpleDateFormat dateFormat = new SimpleDateFormat(Constant.DefaultDateTimePattern);

        mapper = new ObjectMapper();
        mapper.setDateFormat(dateFormat);
        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
            private static final long serialVersionUID = -5854941510519564900L;

            @Override
            public Object findSerializer(Annotated a) {
                if (a instanceof AnnotatedMethod) {
                    AnnotatedElement m = a.getAnnotated();
                    DateTimeFormat an = m.getAnnotation(DateTimeFormat.class);
                    if (an != null) {
                        if (!Constant.DefaultDateTimePattern.equals(an.pattern())) {
                            return new JsonDateSerializer(an.pattern());
                        }
                    }
                }
                return super.findSerializer(a);
            }
        });
    }

    private static class JsonDateSerializer extends JsonSerializer<Date> {
        private SimpleDateFormat dateFormat;

        private JsonDateSerializer(String format) {
            dateFormat = new SimpleDateFormat(format);
        }

        @Override
        public void serialize(Date date, JsonGenerator gen, SerializerProvider provider) throws IOException {
            String value = dateFormat.format(date);
            gen.writeString(value);
        }
    }

    /**
     * 对象转Json字符串
     */
    public static String serialize(Object object) {
        return serialize(object, false);
    }

    /**
     * 对象转Json字符串
     */
    public static String serialize(Object object, boolean isPretty) {
        if (object == null) {
            return "";
        }
        String jsonString;
        try {
            if (isPretty) {
                jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
            } else {
                jsonString = mapper.writeValueAsString(object);
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换json字符失败!", e);
        }
        return jsonString;
    }

    /**
     * Json字符串转对象
     */
    public static <T> T deserialize(String data, Class<T> c) {
        try {
            return mapper.readValue(data, c);
        } catch (IOException e) {
            throw new RuntimeException("将json字符转换为对象时失败!", e);
        }
    }
}
